package com.util;

import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.util.Calendar;
import java.util.Date;

/**
 * @author: cxt
 * @time: 2021/4/26
 * <p>
 * 日期工具类
 */
public class DateUtil extends org.apache.commons.lang3.time.DateUtils {
    public static final int SECONDS_IN_DAY = 60 * 60 * 24;

    public static final long MILLIS_IN_DAY = 1000L * SECONDS_IN_DAY;

    // 时区偏移对象
    private static final ZoneOffset zoneOffset = ZoneOffset.ofHours(8);
    // 时区偏移量（毫秒）
    private static final long millisOffset = zoneOffset.getTotalSeconds() * 1000L;

    public static final Date MAX_DATE = Date.from(LocalDate.parse("9999-12-31").atStartOfDay().toInstant(zoneOffset));

    public static long getOffset() {
        //return TimeZone.getDefault().getOffset(...);
        /** 由于国内不存在夏令时，所以可以直接获取时区偏移量，如果需要可改为TimeZone去获取偏移量*/
        return millisOffset;
    }

    /**
     * 获取服务器启动时间
     */
    public static Date getServerStartDate() {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    /**
     * 计算相差天数
     */
    public static int differentDaysByMillisecond(Date date1, Date date2) {
        return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
    }

    /**
     * 计算两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }

    /**
     * 查找当前月最后一天
     *
     * @param date 月数
     * @return 时间字符串
     */
    public static String getLastDayOfMonth(final Date date) {
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        final int last = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, last);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(cal.getTime());
    }

    /**
     * 开始年份日期加一年
     *
     * @param time 开始年份
     * @return 次年
     */
    public static Date TimeConversion(Date time) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(time);
        cal.add(Calendar.MONTH, 1);
        return cal.getTime();
    }


    /**
     * 获取上个月最后一天
     *
     * @param date 当前时间
     * @return 最后一天时间
     */
    public static Date getLastMonthEndTime(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MONTH, -1);
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        c.set(Calendar.MILLISECOND, 999);
        return c.getTime();
    }

    /**
     * 字符串转成时间
     *
     * @param str 时间字符串，yyyy-MM-dd HH:ss:mm格式
     * @return 时间类型
     */
    public Date strToTime(String str) {
        SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd HH:ss:mm");
        Date parse = null;
        try {
            parse = date.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return parse;
    }

    /**
     * 时间转成字符串
     *
     * @param date 时间
     * @return 字符串
     */
    public static String getStrTime(Date date, SimpleDateFormat format) {
        return format.format(date);
    }

    /**
     * 根据指定格式返回当前时间
     *
     * @param pattern
     * @return
     */
    public static String dateNowByStr(String pattern) {
        Date date = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        return formatter.format(date);
    }

    /**
     * 获取当天零点日期
     *
     * @return 当天零点日期
     */
    public static Date getDayZeroPoint() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0); // 分钟清零，分钟会放在最后
        calendar.set(Calendar.HOUR_OF_DAY, 0); // 小时清零，几点中的整数
        calendar.set(Calendar.MILLISECOND, 0); // 毫秒清零
        return calendar.getTime();
    }


    /**
     * 获取某天的过去几天
     *
     * @param millis   时间戳
     * @param pastDays 过去多少天，负数则为未来多少天
     */
    public static Date getDateBefore(long millis, int pastDays) {
        millis = millis - ((millis + getOffset()) % MILLIS_IN_DAY);
        return new Date(millis - MILLIS_IN_DAY * pastDays);
    }
}
